#!/bin/sh
#
# guesscfg.sh -	Create a config.h file based on guesses.
#		Called by `config.sh' like this:
#
#			. ./guesscfg.sh $system
#
# This script produces just a first guess that might be ok if your system's
# include files are sane -- i.e. rarely.
# Please read file INSTALL for the constants you should define in `config.h'.
#

echo "guessing config.h for ${system:=$1}" >&2

if [ $system = WATCOM ]
then
  make="make TARGET=${TARGET:-OS2V2}"
else
  make=make
fi

case $system in
  EMX)
    o=.o		# object file extension
    e=.exe		# executable file extension
    null=NUL		# null-device name
    ;;
  WATCOM|OS2-ICC)
    o=.obj
    e=.exe
    null=NUL
    ;;
  *)
    o=.o
    e=
    null=/dev/null
    ;;
esac

#
# Some shortcuts, -- yes your shell should know about shell functions :-)
#

tmpc=tmp$$
trap "rm -f $tmpc*; exit 0" 0 1 2 3 15

if [ "`echo -n asdf`" = "asdf" ]
then
  echo_n ()
  {
    echo -n "$@"
  }
else
  echo_n ()
  {
    echo "$@"'\c'
  }
fi

define ()		# a shortcut to add #define-lines to config.h
{
  echo '#define' $1 1
}

includes=""

hasinc ()		# test if an include file is available
{
  echo_n "$1 ... " >&2
  echo "#include <$1>" > $tmpc.c
  rm -f $tmpc.i
  if $make $tmpc.i >$null 2>&1
  then
    echo "yes" >&2
    includes=$includes" $1"
    rm -f $tmpc.c $tmpc.i
    return 0
  else
    echo "no" >&2
    rm -f $tmpc.c $tmpc.i
    return 1
  fi
}

cppinc ()		# output a preprocessed copy of include files to
{			# the standard output.
  for file
  do
    echo "#include <$file>" > $tmpc.c
    rm -f $tmpc.i
    if $make $tmpc.i 2>$null
    then
      cat $tmpc.i
    fi
  done
  rm -f $tmpc.c $tmpc.i
}

grepinc ()		# search strings in system include files
{
  gi_text="$1"
  shift
  test `cppinc $* | grep -c $gi_text` -gt 0
  return $?
}

has ()			# search identifier in system include files
{
  echo_n "$1 ... " >&2
  ha_symbol="[^a-zA-Z0-9]$1[^a-zA-Z0-9]"
  shift
  if grepinc "$ha_symbol" "$@"
  then
    echo "yes" >&2
    return 0
  else
    echo "no" >&2
    return 1
  fi
}

compile ()
{
  echo_n "$1 ... " >&2
  shift

  rm -f $tmpc.c $tmpc$o
  for i
  do
    echo $i >> $tmpc.c
  done

  if $make $tmpc$o >$null 2>&1
  then
    echo "yes" >&2
    rm -f $tmpc.c $tmpc$o
    return 0
  else
    echo "no" >&2
    rm -f $tmpc.c $tmpc$o
    return 1
  fi
}


#
# Start output of `config.h':
#

{

echo "/*
 * config.h --	Automatically generated file, don't change.
 */

#ifndef __CONFIG_H
#define __CONFIG_H
"

echo '#define HOST_SYSTEM "'$system'"'
define $system


#
# Make some assumptions about the kind of system.
#

if [ -n "$PATH" ]
then
  case $PATH in
    ""|*/*)
      # PATH variable looks unix-like:
      # Assume UNIX file name conventions and ISO-latin1 character set.
      define UNIX_FILENAMES
      define ISO_CHARSET
      ;;
    *)
      # PATH variable looks more like DOS:
      # (ok, this is default. It seems impossible to get the quoting of the \
      #  inside the pattern right for more than one shell at a time.)
      # Assume DOS file name conventions and IBMPC character set.
      define DOS_FILENAMES
      define IBMPC_CHARSET
      ;;
  esac
else
  define UNIX_FILENAMES
  define ISO_CHARSET
fi


#
# prepare for "nonansi.h", check available include files.
#

if hasinc sys/types.h;	then define HAVE_SYS_TYPES_H;	fi
if hasinc sys/ioctl.h;	then define HAVE_SYS_IOCTL_H;	fi
if hasinc fcntl.h;	then define HAVE_FCNTL_H;	fi
if hasinc sys/stat.h;	then define HAVE_SYS_STAT_H;	fi
if hasinc direct.h;	then define HAVE_DIRECT_H;	fi
if hasinc sys/ndir.h;	then define HAVE_SYS_NDIR_H;	fi
if hasinc utime.h;	then define HAVE_UTIME_H;	fi
if hasinc sys/time.h;	then define HAVE_SYS_TIME_H;	fi
if hasinc sys/utime.h;	then define HAVE_SYS_UTIME_H;	fi
if hasinc process.h;	then define HAVE_PROCESS_H;	fi
if hasinc sys/process.h;then define HAVE_SYS_PROCESS_H;	fi
if hasinc poll.h;	then define HAVE_POLL_H;	fi
if hasinc sys/poll.h;	then define HAVE_SYS_POLL_H;	fi
if hasinc sys/select.h;	then define HAVE_SYS_SELECT_H;	fi
if hasinc unistd.h;	then define HAVE_UNISTD_H;	fi
if hasinc io.h;		then define HAVE_IO_H;		fi
if hasinc libc.h;	then define HAVE_LIBC_H;	fi
if hasinc dos.h;	then define HAVE_DOS_H;		fi
if hasinc mem.h;	then define HAVE_MEM_H;		fi
if hasinc memory.h;	then define HAVE_MEMORY_H;	fi
if hasinc strings.h;	then define HAVE_STRINGS_H;	fi

if hasinc getopt.h;	then define HAVE_GETOPT_H;	fi
if hasinc locale.h;	then define HAVE_LOCALE_H;	fi

if hasinc termios.h;	then define HAVE_TERMIOS_H;	fi 
if hasinc termio.h;	then define HAVE_TERMIO_H;	fi
if hasinc sgtty.h;	then define HAVE_SGTTY_H;	fi
if hasinc curses.h;	then define HAVE_CURSES_H;	fi
if hasinc term.h;	then define HAVE_TERM_H;	fi
if hasinc termcap.h;	then define HAVE_TERMCAP_H;	fi
if hasinc conio.h;	then define HAVE_CONIO_H;	fi

# echo $includes >&2

#
# check for individual features or lack thereof inside include files.
#

funnyincs=""
for inc in unistd.h io.h libc.h direct.h sys/ndir.h
do
  case $includes in
    *$inc*)
      funnyincs=$funnyincs" $inc"
      ;;
  esac
done

# echo $funnyincs >&2

if has atexit stdlib.h
then
  echo "#define eXit(X) exit(X)"
else
  echo "typedef void (*atexit_fp) (void);"
  echo "int atexit (atexit_fp);"
  echo "void eXit (int);"
fi

if grepinc 'int.*sprintf' stdio.h
then
  : sprintf probably ok
else
  echo "#define WRONG_SPRINTF /* does your sprintf() really return char* ? */"
fi

if grepinc fpos_t stdio.h sys/types.h
then :
else
  echo "#define fpos_t long"
fi

if has random stdlib.h $funnyincs
then
  define HAVE_RANDOM
fi

if has acosh math.h
then
  define HAVE_AH_TRIG
else
  echo "double acosh (double);"
  echo "double asinh (double);"
  echo "double atanh (double);"
fi

if has pow10 math.h
then :
else
  echo "#define pow10(X) pow (10.0, (X))"
fi

if has memmove string.h mem.h memory.h
then
  define HAVE_MEMMOVE
elif has bcopy strings.h
then
  echo "#define memmove(D,S,C) bcopy (S, D, C)"
  define HAVE_MEMMOVE
else
  echo "void memmove (char *, const char *, unsigned);"
fi

#if has stpcpy string.h
#then
#  :
#else
#  echo "#define stpcpy(DST,SRC) (strcpy(DST,SRC) + strlen(SRC))"
#fi

if has strdup string.h
then
  define HAVE_STRDUP
else
  echo "char *strdup (const char *);"
fi

if has strerror string.h
then :
else
  if has sys_errlist stdio.h
  then :
  else
    # well if it doesn't exist, you'll have to write it yourself.
    echo "extern char *sys_errlist [];"
  fi
  echo "#define strerror(x) sys_errlist [x]"
fi

if has remove stdio.h $funnyincs
then
  echo "#define HAVE_REMOVE 1"
else
  echo "#define remove unlink"
fi

if has rename stdio.h $funnyincs
then
  define HAVE_RENAME
else
  echo "int rename (const char *, const char *);"
fi

if has access $funnyincs
then
  define HAVE_ACCESS
else
  echo "int access (const char *fn, int how);"
fi

if has getcwd $funnyincs
then :
else
  echo "#define getcwd(P,L) getwd(P)"
fi

if has stat sys/stat.h $funnyincs
then
  define HAVE_STAT
fi

if has fstat sys/stat.h $funnyincs
then
  define HAVE_FSTAT
fi

if has fileno stdio.h $funnyincs
then
  define HAVE_FILENO
fi

if has truncate $funnyincs
then
  define HAVE_TRUNCATE
else
  echo "int truncate (const char *path, long length);"
fi

if has umask sys/stat.h $funnyincs
then
  define HAVE_UMASK
fi

if has link $funnyincs
then
  define HAVE_LINK
fi

if has getpid $funnyincs process.h sys/process.h
then
  define HAVE_PID
fi

if has getuid $funnyincs process.h sys/process.h
then
  define HAVE_UID
fi

if has getgid $funnyincs process.h sys/process.h
then
  define HAVE_GID
fi

# Time related:
if has usleep stdlib.h time.h sys/time.h $funnyincs
then
  define HAVE_USLEEP
fi

if has select stdlib.h time.h sys/time.h sys/select.h $funnyincs
then
  define HAVE_SELECT
fi

if has delay dos.h conio.h i86.h $funnyincs
then
  define HAVE_DELAY
fi

if has _sys_siglist signal.h sys/signal.h $funnyincs
then
  define HAVE_SYS_SIGLIST
  echo "#define sys_siglist _sys_siglist"
else
  if has sys_siglist signal.h sys/signal.h $funnyincs
  then
    define HAVE_SYS_SIGLIST
  fi
fi

if has raise signal.h sys/signal.h $funnyincs
then
  define HAVE_RAISE
else
  echo "#define raise(X) kill (getpid (), X)"
fi

if has ospeed termcap.h
then
  define HAVE_OSPEED
fi


if has optind getopt.h $funnyincs
then
  : # I assume optarg is defined too.
else
  echo "extern int optind;"
  echo "extern char *optarg;"
fi

#
# Compiler properties.
#

if compile const \
   "const char *p;"
then : # ok, compiler did grok const.
else
  echo "#define const"
fi

if compile "ANSI cpp" \
   "#define STR(X) #X" \
   "char s [] = STR(asdf);"
then : # ok, compiler did understand #X substitution.
else
  define OLDCPP
fi

} > config.h


#
# Determine Cell type, byte sex and alignment restrictions:
#

$make clean >&2
rm -f check_c$e check_c$o
if $make check_c$e >&2
then
  ./check_c$e >> config.h
  rm -f check_c$e check_c$o
else
  echo compiling test program failed >&2
  echo aborting. >&2
  rm -f check_c$e check_c$o
  exit 1
fi

echo "
#endif" >> config.h

# Some shells need this explicitly to execute the trap-code.
exit 0
